import re
import datetime

from Config import *
from Parser import *
from InputProperty import InputProperty
from OutputProperty import OutputProperty

StrColumnAmount = "金额"
StrColumnMerchant = "交易对方"
StrColumnDescription = "商品说明"
StrColumnCategory = "交易分类"
StrOutput = "支出"
StrDateFormat1 = "(\d{4})-(\d{2})-(\d{2})"
StrDateFormat2 = "(\d{4})/(\d{1,2})/(\d{1,2})"
StrDateFormat3 = "(\d{1,2})/(\d{1,2})/(\d{4})"

class ParserZFB(Parser):
    def __init__(self, owner):
        super().__init__(owner)
        self.__itemCategoryIndices = {}

    def _doParse(self, line):
        if self.__handleItemCategory(line):
            return
        if self.__isUselessLine(line):
            return        
        input = InputProperty()
        input.Datetime = self.__getItemDate(line)
        input.Amount = self.__getItemAmount(line)
        input.Merchant = self.__getItemMerchant(line)
        input.Description = self.__getItemDescription(line)
        input.Category = self.__getItemCategory(line)
        self.InputProperties.append(input)

    def _generateOutputs(self):
        for input in self.InputProperties:
            output = OutputProperty()
            output.Owner = self.BillOwner
            output.Datetime = input.Datetime
            output.Amount = input.Amount
            output.Currency = self.__getItemCurrency()
            output.Category, output.Auto = self.__getOutputCategory(input)
            output.PayMethod = PayMethod.Alipay
            output.Note = self.__getItemNote(input)
            self.OutputProperties.append(output)

    def __handleItemCategory(self, line):
        if len(self.__itemCategoryIndices) > 0:
            return False
        index = 0
        for column in [i.strip() for i in line.split(SEPARATOR)]:
            if column == StrColumnAmount or column == StrColumnMerchant or column == StrColumnDescription or column == StrColumnCategory:
                self.__itemCategoryIndices[column] = index
            index += 1
        return True if len(self.__itemCategoryIndices) > 0 else False
        
    def __isUselessLine(self, line):
        if not re.search(StrDateFormat1, line) and not re.search(StrDateFormat2, line) and not re.search(StrDateFormat3, line):
            return True
        return not re.search(StrOutput, line)
    
    def __getItemDate(self, line):
        search = re.search(StrDateFormat1, line)
        if search:
            year = int(search.group(1))
            month = int(search.group(2))
            day = int(search.group(3))
            return datetime.date(year, month, day)
        search = re.search(StrDateFormat2, line)
        if search:
            year = int(search.group(1))
            month = int(search.group(2))
            day = int(search.group(3))
            return datetime.date(year, month, day)
        search = re.search(StrDateFormat3, line)
        if search:
            year = int(search.group(3))
            month = int(search.group(1))
            day = int(search.group(2))
            return datetime.date(year, month, day)
    
    def __getItemAmount(self, line):
        return float(line.split(SEPARATOR)[self.__itemCategoryIndices[StrColumnAmount]].strip())

    def __getItemMerchant(self, line):
        return line.split(SEPARATOR)[self.__itemCategoryIndices[StrColumnMerchant]].strip()

    def __getItemDescription(self, line):
        return line.split(SEPARATOR)[self.__itemCategoryIndices[StrColumnDescription]].split("-")[0].split("_")[0].split(":")[0].split("|")[0].strip()

    def __getItemCurrency(self):
        return Currency.CNY
        
    def __getItemCategory(self, line):
        return line.split(SEPARATOR)[self.__itemCategoryIndices[StrColumnCategory]].strip()

    def __getOutputCategory(self, input):        
        items = [input.Category, input.Merchant, input.Description]
        return self._getOutputCategory(items)

    def __getItemNote(self, input):
        return INNER_SEPARATOR.join([input.Category, input.Merchant, input.Description])
